package com.dashu.school.service;

import com.dashu.base.enums.ReplRyCode;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.school.dto.company.CompanyClsDTO;
import com.dashu.school.dto.company.CompanyDTO;
import com.dashu.school.dto.company.CompanyDepartmentDTO;
import com.dashu.school.handler.VerificationException;
import com.dashu.school.model.CompanyCls;
import com.dashu.school.model.CompanyPersonal;
import com.dashu.school.model.QCompanyCls;
import com.dashu.school.model.TeacherCls;
import com.dashu.school.result.PageEnty;
import com.dashu.school.vo.UpdateEntityVO;
import com.dashu.school.vo.company.CompanyClsListVO;
import com.dashu.school.vo.company.CompanyClsVO;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class CompanyClsService extends DataService {

    @Autowired
    private CompanyService companyService;
    @Autowired
    private TeacherClsService teacherClsService;
    @Autowired
    private CompanyDepartmentService companyDepartmentService;
    @Autowired
    private CompanyPersonalService companyPersonalService;

    @Transactional
    public CompanyClsDTO add(CompanyClsVO companyClsVO) {
        CompanyCls companyCls = CopyUtil.copyEnty(companyClsVO, CompanyCls.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            companyCls.setId(UIDUtil.nextId());
            companyCls.setCreateUser(userId);
            companyCls.setCreateTime(System.currentTimeMillis());
            entityManager.persist(companyCls);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        CompanyClsDTO companyClsDTO = CopyUtil.copyEnty(companyCls, CompanyClsDTO.class);
        return companyClsDTO;

    }

    @Transactional
    public boolean deleteByCompanyClsId(long companyClsId) {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        List<CompanyPersonal> companyPersonals = companyPersonalService.findByCompanyClsId(companyClsId);
        if (companyPersonals.size() > 0)
            throw new VerificationException(ReplRyCode.EXIST_GL_PERSONAL, ReplRyCode.EXIST_GL_PERSONAL.getMessage());
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.id.eq(companyClsId));
        List<TeacherCls> teacherCls = teacherClsService.teacherClsList(0, companyClsId);
        teacherCls.stream().forEach(tc -> {
            teacherClsService.deleteByTeacherClsId(tc.getId());
        });
        CompanyCls companyCls;
        queryFactory.select();
        companyCls = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue()).fetchOne();
        if (companyCls == null)
            throw new VerificationException(ReplRyCode.COMPANY_DEPARTMENT_NOT_DATA, ReplRyCode.COMPANY_DEPARTMENT_NOT_DATA.getMessage());
        entityManager.remove(companyCls);
//            entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        return true;

    }

    @Transactional
    public CompanyClsDTO updataByCompanyClsId(UpdateEntityVO<CompanyClsVO> updateCompanyClsVO) throws Exception {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        CompanyClsVO companyClsVO = updateCompanyClsVO.getEntityVO();
        CompanyClsDTO companyDTO = existByCompanyClsName(companyClsVO.getClsName(), companyClsVO.getDepartmentId());
        if (companyDTO != null) {
            throw new VerificationException(ReplRyCode.EXIST_COMPANY, ReplRyCode.EXIST_COMPANY.getMessage());
        }
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.id.eq(updateCompanyClsVO.getId()));
        CompanyCls companyCls;
        try {
            companyCls = queryFactory
                    .select(qCompanyCls)
                    .from(qCompanyCls)
                    .where(booleanBuilder.getValue()).fetchOne();
            if (companyCls == null)
                throw new VerificationException(ReplRyCode.COMPANY_DEPARTMENT_NOT_DATA, ReplRyCode.COMPANY_DEPARTMENT_NOT_DATA.getMessage());
            companyCls.setUpdateUser(userId);
            companyCls.setUpdateTime(new Date().getTime());
            if (companyClsVO.getClsName() != null)
                companyCls.setClsName(companyClsVO.getClsName());
            if (companyClsVO.getDepartmentId() != 0)
                companyCls.setDepartmentId(companyClsVO.getDepartmentId());
            if (companyClsVO.getPeopleNum() != 0)
                companyCls.setPeopleNum(companyClsVO.getPeopleNum());
            companyCls = entityManager.merge(companyCls);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
//        entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        CompanyClsDTO CompanyClsDTO = CopyUtil.copyEnty(companyCls, CompanyClsDTO.class);
        return CompanyClsDTO;

    }

    public List<CompanyClsDTO> findByCreteUser(PageEnty<Long> baseVo) {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.createUser.eq(baseVo.getBaseId()));
        List<CompanyCls> companyClss = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue())
                .fetch();
        List<CompanyClsDTO> recycleDTOS = CopyUtil.copyList(companyClss, CompanyClsDTO.class);
        return recycleDTOS;

    }


    public List<CompanyCls> findByDepartmentId(long departmentId) {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.departmentId.eq(departmentId));
        List<CompanyCls> companyClss = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue())
                .fetch();
        return companyClss;

    }
    public List<CompanyCls> findByCompanyId(long companyId) {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.companyId.eq(companyId));
        List<CompanyCls> companyClss = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue())
                .fetch();
        return companyClss;

    }

    public CompanyClsDTO findByCompanyClsId(long companyClsId) {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.id.eq(companyClsId));
        CompanyCls companyCls = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue()).fetchOne();
//        if (companyCls == null)
//            throw new VerificationException(ReplRyCode.COMPANY_DEPARTMENT_NOT_DATA, ReplRyCode.COMPANY_DEPARTMENT_NOT_DATA.getMessage());
        CompanyClsDTO CompanyClsDTO = CopyUtil.copyEnty(companyCls, CompanyClsDTO.class);
        return CompanyClsDTO;

    }

    public CompanyClsDTO existByCompanyClsName(String companyClsName, long departmentId) {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qCompanyCls.clsName.eq(companyClsName));
        booleanBuilder.and(qCompanyCls.departmentId.eq(departmentId));
        CompanyCls companyCls = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue()).fetchOne();
        CompanyClsDTO CompanyClsDTO = CopyUtil.copyEnty(companyCls, CompanyClsDTO.class);
        return CompanyClsDTO;

    }

    public long clsCount(PageEnty<CompanyClsListVO> clsListPageEntyVO) throws Exception {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        long baseId = clsListPageEntyVO.getBaseId() == 0 ? userId : clsListPageEntyVO.getBaseId();
        CompanyClsListVO companyClsListVO = clsListPageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        if (companyClsListVO.getDepartmentId() != 0) {
            booleanBuilder.and(qCompanyCls.createUser.eq(clsListPageEntyVO.getBaseId()));
        } else if (!StringUtils.isEmpty(companyClsListVO.getClsName())) {
            booleanBuilder.and(qCompanyCls.createUser.eq(clsListPageEntyVO.getBaseId()));
        } else {
            List<Long> companys = Lists.newArrayList();
            companyService.findByBaseId(baseId).stream().forEach(cd -> {
                companys.add(cd.getId());
            });
            booleanBuilder.and(qCompanyCls.companyId.in(companys));
        }
        long count = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue())
                .fetchCount();
        return count;
    }

    public List<CompanyClsDTO> pageClsList(PageEnty<CompanyClsListVO> clsListPageEntyVO) throws Exception {
        QCompanyCls qCompanyCls = QCompanyCls.companyCls;
        List<CompanyClsDTO> recycleDTOS = Lists.newArrayList();
        long userId = Long.parseLong(VerificationUtil.getUserId());
        long baseId = clsListPageEntyVO.getBaseId() == 0 ? userId : clsListPageEntyVO.getBaseId();
        CompanyClsListVO companyClsListVO = clsListPageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        if (companyClsListVO.getDepartmentId() != 0) {
            booleanBuilder.and(qCompanyCls.departmentId.eq(companyClsListVO.getDepartmentId()));
        } else if (!StringUtils.isEmpty(companyClsListVO.getClsName())) {
            booleanBuilder.and(qCompanyCls.clsName.like("%" + companyClsListVO.getClsName() + "%"));
        } else if (companyClsListVO.getCompanyId() != 0) {
            booleanBuilder.and(qCompanyCls.companyId.eq(companyClsListVO.getCompanyId()));
        } else {
            List<Long> companys = Lists.newArrayList();
            companyService.findByBaseId(baseId).stream().forEach(cd -> {
                companys.add(cd.getId());
            });
            booleanBuilder.and(qCompanyCls.companyId.in(companys));
        }
        List<CompanyCls> companyClss = queryFactory
                .select(qCompanyCls)
                .from(qCompanyCls)
                .where(booleanBuilder.getValue())
                .offset((clsListPageEntyVO.getPage() - 1) * clsListPageEntyVO.getNum())
                .limit(clsListPageEntyVO.getNum())
                .orderBy(qCompanyCls.createTime.desc())
                .fetch();
        companyClss.stream().forEach(cc -> {
            CompanyClsDTO companyClsDTO = CopyUtil.copyEnty(cc, CompanyClsDTO.class);
            CompanyDTO companyDTO = companyService.findByCompanyId(cc.getCompanyId());
            CompanyDepartmentDTO companyDepartmentDTO = companyDepartmentService.findByCompanyDepartmentId(cc.getDepartmentId());
            companyClsDTO.setCompanyName(companyDTO.getCompanyName());
            if (companyDepartmentDTO != null)
                companyClsDTO.setDepartmentName(companyDepartmentDTO.getGradeName());
            companyClsDTO.setClsName(cc.getClsName());
            recycleDTOS.add(companyClsDTO);
        });

        return recycleDTOS;

    }


}
